/*
 * Copyright (C) 2022 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef TYPES_H
#define TYPES_H

#include <QtGlobal>
#include <QRect>
#include <QString>
#include <QList>
#include <QDebug>

#define DEFAULT_GROUP_NAME_PREFIX "0#"
#define CUSTOM_GROUP_NAME_PREFIX "1#"

namespace UKUI {

enum class Type {
    Icon = 1,
    Group,
    Container,
    Widget,
    Unknown
};

class BaseItem : public QObject
{
    Q_OBJECT
public:    
    enum Categories {
        All,
        Mobile,
        Internet,
        Social,
        Video,
        Development,
        Image,
        Game,
        Office,
        Education,
        System,
        Safe,
        Others
    };
    Q_ENUM(Categories);

    BaseItem(QString name, qint32 id, QList<int> categories = {-1}, Type type = Type::Unknown, QList<int> placeholder = {1,1}) :
        m_name(name), m_identify(id), m_type(type), m_placeholder(placeholder), m_categories(categories) {}
    virtual ~BaseItem() {}

    void setName(QString name) {
        m_name = name;
    }
    QString getName() const {
        return m_name;
    }
    void setId(qint32 id) {
        m_identify = id;
    }
    quint32 getId() const {
        return m_identify;
    }
    void setType(Type type) {
        m_type = type;
    }
    Type getType() const {
        return m_type;
    }
    void setPlaceHolder(QList<int> place) {
        m_placeholder = place;
    }
    QList<int> getPlaceHolder() const {
        return m_placeholder;
    }
    void setCategories(QList<int> categories) {
        m_categories = categories;
    }
    QList<int> getCategories() const {
        return m_categories;
    }

private:
    QString m_name;
    quint32 m_identify;
    Type m_type;
    QList<int> m_placeholder;
    QList<int> m_categories;
};

class IconItem : public BaseItem
{
public:
    IconItem(QString desktopName, QString name, qint32 id, QString iconName, QList<int> categories, Type type = Type::Icon) :
        BaseItem(name, id, categories, type), m_desktopName(desktopName), m_icon(iconName) {}
    ~IconItem() {}
    QString getDesktopName() const {
        return m_desktopName;
    }
    const QString getIconName() const {
        return m_icon;
    }
    void setIconName(QString name) {
        m_icon = name;
    }
private:
    QString m_desktopName;
    QString m_icon;
};

class Widget : public BaseItem
{
public:
    Widget(QString qmlFilePath, QString name, qint32 id, QList<int> placeholder, Type type = Type::Widget) :
        BaseItem(name, id, {-1}, type, placeholder), m_qmlFilePath(qmlFilePath) {}
    ~Widget() {}
    QString getQmlFilePath() const {
        return m_qmlFilePath;
    }

private:
    QString m_qmlFilePath;
};

class GroupItem : public BaseItem
{
public:
    GroupItem(QString name, qint32 id, Type type = Type::Group) :
        BaseItem(name, id, {-1}, type) { setSourceName(name); }
    bool isScrollLayout() {
        return isScrollable;
    }
    void setScrollLayout(bool scroll) {
        isScrollable = scroll;
    }
    ~GroupItem() {}
    void setSourceName(QString name) {
        sourceName = name;
    }
    QString getSourceName() const{
        return sourceName;
    }
private:
    bool isScrollable;
    QString sourceName;
};

class ContainerItem : public BaseItem
{
public:
    ContainerItem(QString name, qint32 id, QList<int> placeholder = {2,2}, bool titleEditable = false,
                  bool containerEditable = false, QString containerCategory = "null", Type type = Type::Container) :
        BaseItem(name, id, {-1}, type, placeholder), m_titleEditable(titleEditable),
                 m_containerEditable(containerEditable), m_containerCategory(containerCategory) {}
    ~ContainerItem() {}
    bool isScrollLayout() {
        return isScrollable;
    }
    void setScrollLayout(bool scroll) {
        isScrollable = scroll;
    }
    bool isTitleEditable() const {
        return m_titleEditable;
    }
    bool isContainerEditable() const {
        return m_containerEditable;
    }
    QString getContainerCategory() const {
        return m_containerCategory;
    }
private:
    bool isScrollable;
    bool m_titleEditable;
    bool m_containerEditable;
    QString m_containerCategory;
};

using ItemId = int;
using ItemMap = QMap<ItemId, BaseItem *>;
using ItemIdInPageList = QList<int>;
using ItemIdInSetMap = QMap<int, QList<QList<int>>>;
using ItemIdInHomeScreenMap = QMap<int, QList<int>>;
using ItemIdsPage = QList<QList<int>>;
using CategoryIntList = QList<int>;
using CategoryStringMap = QMap<QString, QString>;
using ItemInPageGridMap = QMap<int, QList<QList<int>>>;

}

#endif // TYPES_H
